/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.commands;

import org.eclipse.gef.commands.Command;

import com.cea.papyrus.core.helper.IGraphElementHelper;
import com.cea.papyrus.core.helper.ModelerHelper;
import com.cea.papyrus.core.helper.NodeHelper;
import com.cea.papyrus.core.utils.LookForElement;
import com.cea.papyrus.diagraminterchange2.di2.Diagram;
import com.cea.papyrus.diagraminterchange2.di2.GraphElement;
import com.cea.papyrus.diagraminterchange2.di2.GraphNode;
import com.cea.papyrus.diagraminterchange2.di2.Uml1SemanticModelBridge;


/**
 * A command to remove a shape from its parent.
 * The command can be undone or redone.
 */
public class GraphNodeDeleteCommand extends Command {

	/**
	 * Shape to remove.
	 */
	protected final GraphNode child;

	/**
	 * ShapeDiagram to remove from.
	 */
	protected final GraphElement parent;

	/**
	 * True, if child was removed from its parent.
	 */
	protected boolean wasRemoved;

	/**
	 * 
	 */
	protected IGraphElementHelper elementFactory;

	/**
	 * Create a command that will remove the shape from its parent.
	 * 
	 * @param child    the Shape to remove
	 * @param parent the ShapesDiagram containing the child
	 * 
	 * @throws IllegalArgumentException if any parameter is null
	 */
	public GraphNodeDeleteCommand(GraphElement parent, GraphNode child) {
		if ((parent == null) || (child == null)) {
			throw new IllegalArgumentException();
		}

		//look for the good factory
		if (child.getSemanticModel()!=null && ((Uml1SemanticModelBridge)child.getSemanticModel()).getElement()!=null) {
			// get the type of the diagram that owns the graph node to be deleted
			String type = null;
			Diagram dia = LookForElement.getDiagram(parent);
			if(dia!=null) {
				type= dia.getType();
			} 
			java.lang.Class clazz=((Uml1SemanticModelBridge)child.getSemanticModel()).getElement().getClass().getInterfaces()[0];
			//the type may be null, if the notifier of destruction has notified the parent
			if(type!=null){
				this.elementFactory = (IGraphElementHelper)(ModelerHelper.getFactory(type)).getElementFactory(clazz);
			}
			//in the case of null we use the default NodeHelper
			this.elementFactory= new NodeHelper();
		}
		else{
			this.elementFactory= new NodeHelper();
		}	



		setLabel("GraphNode deletion");
		this.parent = parent;
		this.child = child;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#canUndo()
	 */
	/**
	 * 
	 * 
	 * @return 
	 */
	@Override
	public boolean canUndo() {
		return wasRemoved;
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#execute()
	 */
	/**
	 * 
	 */
	@Override
	public void execute() {

		child.setSemanticParent(null);
		wasRemoved = elementFactory.removeGraphElement(child, parent);
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#redo()
	 */
	/**
	 * 
	 */
	@Override
	public void redo() {
		// executte the command again
		execute();
	}

	/* (non-Javadoc)
	 * @see org.eclipse.gef.commands.Command#undo()
	 */
	/**
	 * 
	 */
	@Override
	@SuppressWarnings("unchecked")
	public void undo() {
//		if ( ((Uml1SemanticModelBridge)child.getSemanticModel() != null) 
//		&& (((Uml1SemanticModelBridge)child.getSemanticModel()).getElement() instanceof TemplateSignature) ) {
//		elementFactory.addGraphElement(child, parent) ;
//		child.setSemanticParent(parent) ;
//		}
//		else {
		elementFactory.addGraphElement(child, parent);
//		}
	}
}
